home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*_______________________________________________________________________
- |
- | blixscore.c - handles reading and writing highscores
- |
- | There are three levels of highscore stored at different places
- | the first level is in the users home directory to store the personal
- | highscores. The second is stored in "/usr/tmp/Indyzone/blix" and
- | holds the systemwide scores. The third - more interesting level -
- | holds the worldwide records (for people who can reach the server)
- | The format of the file is the same in all three cases.
- |
- | (c) 1994 Frans van Hoesel, hoesel@chem.rug.nl
- | Xtreme Graphics Software
- |
- */
-
- #include <pwd.h>
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <unistd.h>
- #include <string.h>
- #include <malloc.h>
- #include <alloca.h>
- #include <fcntl.h>
- #include <bstring.h>
- #include <stdlib.h>
-
- #include "blix.h"
- #include "blixnetwork.h"
- #include "blixscore.h"
- #include "blixscore_io.h"
- #include "blixtmpdir.h"
- #include "blixui.h"
-
- int gethostname (char *name, int namelen);
- int world_score_id;
-
- scorelist_t privatlist;
- scorelist_t systemlist;
- scorelist_t worldlist;
-
- static int updatescore(scorelist_t *scorelist, userinfo_t *inf) ;
- static void sort_score(scorelist_t *scorelist);
- static int doprivatescore(userinfo_t *inf);
- static int dosystemscore(userinfo_t *inf);
- static int doworldscore(userinfo_t *inf);
-
- int sginap(long ticks);
-
- void init_tmpdir(void) {
- mode_t cmask;
- int f;
-
- cmask = umask(0000);
- f = open(BLIXTMPDIR, O_RDONLY) ;
- if (f == -1) {
- /* directory does not exists; make it */
- mkdir(TMPDIR1, 0777);
- if (mkdir(BLIXTMPDIR, 0777)) {
- fprintf(stderr,"%s: Cannot create directory '" BLIXTMPDIR "' "
- "for writing temporary data\n", basename );
- cmask = umask(cmask);
- exit(1);
- }
- } else {
- close(f);
- }
- cmask = umask(cmask);
- }
-
- static int openprivatscore(void) {
- userinfo_t *inf;
- char *name;
- int f;
-
- inf = getinf();
- if (inf == NULL) {
- return 0;
- }
- name = (char *)alloca((strlen(inf->home) + 13) * sizeof(char));
- strcpy(name, inf->home);
- strcat(name, "/.blixscore");
- f = openscore(name, 3);
- return f;
- }
-
- static int opensystemscore(void) {
-
- mode_t cmask;
- int f;
-
- cmask = umask(0111);
- f = openscore(BLIXTMPDIR "/systemscore", 15);
- cmask = umask(cmask);
- if (f == -1) {
- fprintf(stderr,"%s: Cannot create file %s\n", basename,
- BLIXTMPDIR "/systemscore");
- }
- return f;
- }
-
- static int openworldscore(void) {
-
- mode_t cmask;
- int f;
-
- cmask = umask(0111);
- f = openscore(BLIXTMPDIR "/worldcache", 15);
- cmask = umask(cmask);
- if (f == -1) {
- fprintf(stderr,"%s: Cannot create file %s\n", basename,
- BLIXTMPDIR "/worldcache");
- }
- return f;
- }
-
- userinfo_t *getinf(void) {
-
- struct passwd *pass;
- struct hostent *hostinfo;
- static userinfo_t uinfo;
- static int done_it = 0;
- char name[256];
- char *cptr;
- char alias[50];
- FILE *f;
- char *s;
-
- if (done_it) {
- return &uinfo;
- }
- done_it = 1;
- cptr = cuserid(NULL);
- if (cptr == NULL) {
- cptr = getlogin();
- }
-
- if (cptr == NULL) {
- fprintf(stderr,"%s: Cannot find your login name\n", basename);
- return NULL;
- }
- strncpy(uinfo.name, cptr, 47);
- uinfo.name[47] = '\0';
- pass = getpwuid(getuid());
- if (pass != NULL && pass->pw_dir != NULL && *(pass->pw_dir) != '\0') {
- strncpy(uinfo.home, pass->pw_dir, 47);
- uinfo.home[47] = '\0';
- strncpy(uinfo.name, pass->pw_name, 47);
- uinfo.name[47] = '\0';
- } else {
- uinfo.home[0] = '\0';
- return NULL;
- }
- if (gethostname(cptr, 256)) {
- uinfo.host[0] = '\0';
- uinfo.addr = 0;
- return NULL;
- } else {
- strncpy(uinfo.host, cptr, 47);
- uinfo.host[47] = '\0';
- }
- cptr[255]=0;
- hostinfo = gethostbyname(cptr);
- if (hostinfo == NULL) {
- uinfo.addr = 0;
- } else {
- strncpy(uinfo.host, hostinfo->h_name, 47);
- uinfo.host[47] = '\0';
- uinfo.addr = (hostinfo->h_addr[0] << 24) |
- (hostinfo->h_addr[1] << 16 ) |
- (hostinfo->h_addr[2] << 8 ) |
- hostinfo->h_addr[3];
- }
-
-
- /* find the users image */
- strcpy(name, uinfo.home);
- strcat(name, "/.bliximage");
- f = fopen(name, "r");
- if (f == NULL) {
- /* try to use pandora's image search */
- strcpy(name, uinfo.home);
- strcat(name, "/.icons/login.icon");
- f = fopen(name, "r");
- if (f == NULL) {
- strcpy(name, "/usr/local/lib/faces/");
- strcat(name, uinfo.name);
- f = fopen(name, "r");
- if ( f == NULL) {
- strcpy(name, "/usr/lib/faces/");
- strcat(name, uinfo.name);
- f = fopen(name, "r");
- if ( f == NULL) {
- *name = '\0';
- }
- }
- }
- }
- if (f != NULL)
- fclose(f);
- strncpy(uinfo.image, name, 128);
- uinfo.image[128] = '\0';
- /* check if user wants to use an alias instead of a real username */
- strcpy(name, uinfo.home);
- strcat(name, "/.blixalias");
- f = fopen(name, "r");
- if (f != NULL) {
- fgets(alias, 48, f);
- while ((s = strchr(alias,'\n')) != NULL) {
- *s = ' ';
- }
- alias[47] = '\0';
- strcpy(uinfo.name, alias);
- fclose(f);
- }
- return &uinfo;
- }
-
- void showscore(int clearin, int score, int fadeout) {
- int cnt;
- int i;
- float v1[3];
-
- uimode = MODE2D;
- if (clearin) {
- cpack(0x00000000);
- switch_single();
- clear();
- }
- /* fade in score display */
- cpack(0x000022bb);
- pushmatrix();
- ortho2(0,1,0,1);
- lmbind(MATERIAL, 0);
- for (i=16; i>=0; i--) {
- setpattern(i);
- bgnqstrip();
- v1[0] = 1; v1[1] = 0;cpack(0x000052ff);
- v2f(v1);
- v1[0] = 1; v1[1] = 1; cpack(0x000038ff);
- v2f(v1);
- v1[0] = 0; v1[1] = 0; cpack(0x000061ff);
- v2f(v1);
- v1[0] = 0; v1[1] = 1; cpack(0x000022bb);
- v2f(v1);
- gsync();
- endqstrip();
- gflush();
- sginap(CLK_TCK/50);
- }
- if (initstat == -1 && score == WORLDHIGH) {
- display_scene = SORRY;
- } else {
- display_scene = score;
- }
- draw_whatever2d();
- cnt = 120;
- while (do_event() == 0 && cnt-- ) {
- sginap(CLK_TCK/10);
- }
- if (fadeout) {
- cpack(0x000000);
- for (i=16; i>= 0; i--) {
- setpattern(i);
- gsync();
- clear();
- gflush();
- sginap(CLK_TCK/50);
- }
- sginap(CLK_TCK/2);
- }
- popmatrix();
- display_scene = GAME;
- uimode = MODE3D;
- }
-
- void doscore(int score) {
- userinfo_t *inf;
- int scored = 0;
- int i;
- inf = getinf();
- inf->score = score;
- disable_pop();
- if (doprivatescore(inf)) {
- showscore(1, PRIVATHIGH, 0);
- scored = 1;
- }
- if (dosystemscore(inf)) {
- showscore((score != 1), SYSTEMHIGH, 0);
- scored = 1;
- }
- if (noworld == 0 && doworldscore(inf) && initstat != -1) {
- showscore((score != 1), WORLDHIGH, 0);
- scored = 1;
- }
- if (scored) {
- cpack(0x000000);
- for (i=16; i>= 0; i--) {
- setpattern(i);
- clear();
- gflush();
- sginap(CLK_TCK/50);
- }
- sginap(CLK_TCK/2);
- }
- enable_pop();
- display_scene = GAME;
- uimode = MODE3D;
- }
-
- static int doprivatescore(userinfo_t *inf) {
- static int first_time = 1;
- int f;
-
- if (first_time) {
- f = openprivatscore();
- readscore(f, &privatlist);
- privatlist.game++;
- sort_score(&privatlist);
- updatescore(&privatlist, inf);
- if (f != -1) {
- lseek(f, SEEK_SET, 0);
- writescore(f, &privatlist);
- close(f);
- }
- first_time = 0;
- } else {
- if (updatescore(&privatlist, inf)) {
- f = openprivatscore();
- if (f != -1) {
- writescore(f, &privatlist);
- close(f);
- }
- return 1;
- }
- }
- return 0;
- }
-
- /*___________________________________________________________________
- |
- | dosystemscore - keep track of system's best players
- |
- | it is different from the privat and world score, because it
- | tries to read the systemscore file at every call. This is
- | so you can play competion with your neighbour.
- */
- static int dosystemscore(userinfo_t *inf) {
- static int first_time = 1;
- int f;
-
- if (first_time) {
- /* read it */
- f = opensystemscore();
- readscore(f, &systemlist);
- systemlist.game++;
- sort_score(&systemlist);
- updatescore(&systemlist, inf);
- if (f != -1) {
- lseek(f, SEEK_SET, 0);
- writescore(f, &systemlist);
- close(f);
- }
- first_time = 0;
- } else {
- f = opensystemscore();
- if (f != -1) {
- readscore(f, &systemlist);
- }
- if (updatescore(&systemlist, inf)) {
- if (f != -1) {
- lseek(f, SEEK_SET, 0);
- writescore(f, &systemlist);
- close(f);
- }
- return 1;
- }
- if (f != -1) {
- close(f);
- }
- }
- return 0;
- }
-
- int get_score(userinfo_t *inf) {
- int f;
- long imageid;
- long imagesize;
- char *imagedata;
- int img;
- int i;
- struct stat statbuf;
- char *slash;
- char tmpstr[256];
- mode_t cmask;
-
- f = openworldscore();
- readscore(f, &worldlist);
- write_server("GSCR", -4);
- write_server(&(worldlist.id), sizeof(long));
- if (server_ready() == 0) {
- read_serverscore(&worldlist);
- closeserver();
- for (i=0; i< 7; i++) {
- /* check if image exists, otherwise request it */
- if (worldlist.images[i] != NULL &&
- *(worldlist.images[i]) != '\0' &&
- stat(worldlist.images[i], &statbuf) != 0) {
- slash = strrchr(worldlist.images[i], '/');
- imageid = atoi(slash+1);
- openserver();
- write_server("GIMG", -4);
- write_server(&imageid, sizeof(long));
- if (server_ready() == 0) {
- read_serverstr(tmpstr);
- read_server(&imagesize, sizeof(long));
- fprintf(stderr,"%s: receiving image %d bytes...",
- basename, (int) imagesize);
- fflush(NULL);
- if (imagesize != 0 && imagesize < 100000) {
- imagedata = (char *)malloc(imagesize);
- read_server(imagedata, -imagesize);
- sprintf(worldlist.images[i],
- BLIXTMPDIR "/%s", tmpstr);
- cmask = umask(0000);
- img = open(worldlist.images[i],
- O_WRONLY | O_CREAT, 0666);
- umask(cmask);
- if (img >= 0) {
- write_data(img, imagedata, -imagesize);
- close(img);
- } else {
- *(worldlist.images[i]) = '\0';
- }
- free(imagedata);
- }
- fprintf(stderr," done\n");
- }
- closeserver();
- }
- }
- world_score_id = worldlist.id;
- sort_score(&worldlist);
- } else {
- sort_score(&worldlist);
- updatescore(&worldlist, inf);
- }
- if (f != -1) {
- lseek(f, SEEK_SET, 0);
- writescore(f, &worldlist);
- close(f);
- }
- return 0;
- }
-
- static int doworldscore(userinfo_t *inf) {
- static int first_time = 1;
- int f;
- long yoursize;
- char *yourimage;
- int img;
- struct stat buf;
-
- /* did we succeed in filling the world info ? */
- if (world_score_id == -1)
- return 0;
- if (first_time) {
- make_connect();
- get_score(inf);
- first_time = 0;
- } else {
- if (updatescore(&worldlist, inf)) {
- if (openserver() == 0) {
- write_server("PSCR", -4);
- write_server(&(inf->score), sizeof(long));
- write_server(inf->name, strlen(inf->name));
- write_server(inf->host, strlen(inf->host));
- write_server(&(inf->addr), sizeof(long));
- if (inf->image != NULL && *(inf->image) != '\0') {
- img = open(inf->image, O_RDONLY);
- yoursize = 0;
- if (img >= 0 && fstat(img, &buf) >= 0) {
- yoursize = buf.st_size;
- }
- write_server(&yoursize, sizeof(yoursize));
- if (yoursize != 0 && yoursize < 100000) {
- yourimage = (char *)malloc(yoursize);
- read_data(img, yourimage, -yoursize);
- write_server(yourimage, -yoursize);
- free(yourimage);
- }
- } else {
- yoursize = 0;
- write_server(&yoursize, sizeof(yoursize));
- }
- closeserver();
- cleanup_images(&worldlist, BLIXTMPDIR, "world");
- }
- f = openworldscore();
- writescore(f, &worldlist);
- close(f);
- return 1;
- }
- }
- return 0;
- }
-
-
- static void sort_score(scorelist_t *scorelist) {
- int i,j;
- char tmps[256];
- long tmp;
-
- for (i = 1; i < 7; i++) {
- j = i;
- while (j > 0 && scorelist->scores[j-1] < scorelist->scores[j]) {
- strcpy(tmps,scorelist->names[j]);
- strcpy(scorelist->names[j], scorelist->names[j-1]);
- strcpy(scorelist->names[j-1], tmps);
- strcpy(tmps, scorelist->hosts[j]);
- strcpy(scorelist->hosts[j], scorelist->hosts[j-1]);
- strcpy(scorelist->hosts[j-1], tmps);
- strcpy(tmps, scorelist->images[j]);
- strcpy(scorelist->images[j], scorelist->images[j-1]);
- strcpy(scorelist->images[j-1], tmps);
- tmp = scorelist->scores[j];
- scorelist->scores[j] = scorelist->scores[j-1];
- scorelist->scores[j-1] = tmp;
- tmp = scorelist->addrs[j];
- scorelist->addrs[j] = scorelist->addrs[j-1];
- scorelist->addrs[j-1] = tmp;
- j--;
- }
- }
- }
-
- static int updatescore( scorelist_t *scorelist, userinfo_t *inf) {
-
- int i;
-
- if (scorelist->scores[6] >= inf->score) {
- return 0;
- }
- /* the high score list records the five persons
- * with the highest scores, not the five highest scores.
- * This is to get more variation on your screen:-)
- */
- i = 6;
- if (scorelist != &privatlist) {
- for (i=0; i< 6; i++) {
- if (scorelist->addrs[i] == inf->addr &&
- strcmp(scorelist->names[i], inf->name) == 0) {
- break;
- }
- }
- }
- while (i > 0 && (scorelist->scores[i-1] < inf->score ||
- ((scorelist->scores[i] == inf->score) &&
- ((scorelist->addrs[i] != inf->addr) ||
- (strcmp(scorelist->names[i], inf->name) != 0))
- ))) {
- strcpy(scorelist->names[i], scorelist->names[i-1]);
- strcpy(scorelist->hosts[i], scorelist->hosts[i-1]);
- strcpy(scorelist->images[i], scorelist->images[i-1]);
- scorelist->scores[i] = scorelist->scores[i-1];
- scorelist->addrs[i] = scorelist->addrs[i-1];
- i--;
- }
- if (scorelist->scores[i] < inf->score ||
- (scorelist->scores[i] == inf->score &&
- (scorelist->addrs[i] != inf->addr ||
- strcmp(scorelist->names[i], inf->name) != 0)
- )) {
- strcpy(scorelist->names[i], inf->name);
- strcpy(scorelist->hosts[i], inf->host);
- strcpy(scorelist->images[i], inf->image);
- scorelist->scores[i] = inf->score;
- scorelist->addrs[i] = inf->addr;
- return 1;
- }
- return 0;
- }
-
- void printscore(char *head, scorelist_t *scorelist) {
- int i;
- fprintf(stderr, "%s\n", head);
- fprintf(stderr, "games: %d id: %d\n", (int) scorelist->game, (int) scorelist->id);
- for (i=0; i<7; i++) {
- fprintf(stderr, "%s (%s) %d", scorelist->names[i],
- scorelist->hosts[i], (int) scorelist->scores[i]);
- if (scorelist->images[i] != NULL)
- fprintf(stderr, " %s", scorelist->images[i]);
- fprintf(stderr, "\n");
- }
-
- }
-
-
- void init_server(void) {
- init_connect();
- }
-